//
//  ParallaxNode.swift
//  soapp
//
//  Created by zhuxietong on 2019/4/30.
//

import Foundation
import Eelay
import AsyncDisplayKit
open class ParallaxNode<Header:EeParallaxHeader>: ASSizeRangeCell {
    open override func sizeRange() -> ASSizeRange {
        let hd = header
        var h = hd.frame.size.height
        h = h - TP.topHeight
        //        print("++++++++|\(h)")
        return ASSizeRange(min: CGSize(width: Swidth, height: h), max: CGSize(width: Swidth, height: h))
        //        return ASSizeRange(min: [Swidth,200], max: [Swidth,200])
    }
    
    open override func addLayoutRules() {
        self.clipsToBounds = false
    }
    
    
    open func initHeader()->Header{
        let height = mo.model[float:"height",Swidth]
        return Header(frame: CGRect(x: 0, y: 0, width: Swidth, height: height))
    }
    
    open var header:Header{
        get{
            if let hd = mo.controller?.__extention["reuseID<\(mo.model["reuseID","EeParallaxHeader"])>"] as? Header //可复用处理
            {
//                hd.mo.model = mo.model
                return hd
            }else{
                let hd = self.initHeader()
                if let ctr = mo.controller{
                    DispatchQueue.main.async(execute: {
                        hd.initWhenControlerDidLoadView(controller: ctr)
                    })
                }
                mo.controller?.__extention["reuseID<\(mo.model["reuseID","EeParallaxHeader"])>"] = hd
//                hd.mo.model = mo.model
                hd.frame = CGRect(x: 0, y: -TP.topHeight, width: hd.frame.width, height:hd.frame.height)
                return hd
            }
        }
    }
    
    override open func mo_model_reload() {
        let head = self.header
        self.view.addSubview(head)
        head.mo.model = mo.model
        
    }
    
    open override func specGetter() -> _Spec {
        return .stack(["\(header.frame.size.height)",Swidth], childs: [])
    }
 
}


open class EeParallaxHeader:JoView{
    
    public var heightLayoutConstraint = NSLayoutConstraint()
    open var miniHeigth:CGFloat{
        get{
            return self.frame.size.height
        }
    }
    public var justHeight:CGFloat{
        get{
            let just = controller?.topLayoutGuide.length ?? TP.topHeight
            return just
        }
    }
    
    public let containerView = UIView()
    
    var topLayoutGuide = TP.topHeight
    public weak var controller:UIViewController? = nil
    public weak var scrollView:UIScrollView? = nil
    {
        willSet{
            scrollView?.removeObserver(self, forKeyPath: "contentOffset")
        }
        didSet{
            let options: NSKeyValueObservingOptions = [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old]
            scrollView?.addObserver(self, forKeyPath: "contentOffset", options: options, context: nil)
        }
    }
    
    public func initWhenControlerDidLoadView(controller:UIViewController) {
        topLayoutGuide = controller.topLayoutGuide.length
        if topLayoutGuide <= 0
        {
            topLayoutGuide = TP.topHeight
        }
        self.controller = controller
        
        self.eelay = [
            [containerView,[ee.L.R.B]],
        ]
        self.heightLayoutConstraint = NSLayoutConstraint(item: containerView, attribute:.height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: self.miniHeigth)
        self.addConstraint(heightLayoutConstraint)
        containerViewDidLoad()
        var scrollView:UIScrollView? = nil
        if let ctr = controller as? ASColListController{
            scrollView = ctr.collectionView
        }
        if let ctr = controller as? ASListController{
            scrollView = ctr.tableView
        }
        if let ctr = controller as? ColsController{
            scrollView = ctr.collectionView
        }
        if let ctr = controller as? ListController{
            scrollView = ctr.tableView
        }
        if let _scrollV = scrollView{
            self.scrollView = _scrollV
        }
    }
    
    
    override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "contentOffset" {
            if let scrollV = self.scrollView
            {
                self.scrollViewDidScroll(scrollView: scrollV)
            }
        }
    }
    
    
    open func containerViewDidLoad() {
        
    }
    
    open func scrollViewDidScroll(scrollView: UIScrollView) {
        let top:CGFloat = justHeight
        let offsetY = (-scrollView.contentOffset.y) - top
        if offsetY < 0{
            return
        }
        self.heightLayoutConstraint.constant = miniHeigth+offsetY
        self.containerView.layoutIfNeeded()
//        containerView.clipsToBounds = offsetY <= 0
    }
    
    deinit {
        scrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    
    
    
}


